package cn.com.bluemoon.daps.model.service.impl;

import cn.com.bluemoon.daps.common.domain.ResultBean;
import cn.com.bluemoon.daps.common.enums.SystemType;
import cn.com.bluemoon.daps.model.dto.register.DapModelRegisterDto;
import cn.com.bluemoon.daps.model.entity.DapDataModel;
import cn.com.bluemoon.daps.model.entity.DapDataModelGroup;
import cn.com.bluemoon.daps.model.entity.DapDataModelShareTable;
import cn.com.bluemoon.daps.model.entity.DapDataModelTable;
import cn.com.bluemoon.daps.model.mapper.DapDataModelShareTableMapper;
import cn.com.bluemoon.daps.model.service.DapDataModelGroupService;
import cn.com.bluemoon.daps.model.service.DapDataModelService;
import cn.com.bluemoon.daps.model.service.DapDataModelShareTableService;
import cn.com.bluemoon.daps.model.service.DapDataModelTableService;
import cn.com.bluemoon.daps.model.vo.share.SearchShareTableVo;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.google.common.collect.Lists;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.util.*;
import java.util.stream.Collectors;

import static org.apache.commons.lang3.StringUtils.isNotBlank;

/**
 * <p>
 * 系统下数仓多模型相互共享表 服务实现类
 * </p>
 *
 * @author admin
 * @since 2021-09-23
 */
@Slf4j
@Service
public class DapDataModelShareTableServiceImpl extends ServiceImpl<DapDataModelShareTableMapper, DapDataModelShareTable>
        implements DapDataModelShareTableService {

    @Resource
    DapDataModelTableService dapDataModelTableService;

    @Resource
    DapDataModelService dataModelService;

    @Resource
    DapDataModelGroupService dapDataModelGroupService;

    @Override
    public boolean isShareModel(String modelId) {
        LambdaQueryWrapper<DapDataModelShareTable> eq = bmLambdaQuery().eq(DapDataModelShareTable::getModelId, modelId);
        return count(eq) != 0;
    }

    @Override
    public Set<String> matchShareModels(Set<String> modelIds) {
        if (modelIds != null && !modelIds.isEmpty()) {
            return modelIds.stream().distinct().filter(this::isShareModel).collect(Collectors.toSet());
        }
        return Collections.emptySet();
    }

    @Override
    public IPage<DapDataModelTable> getShareModelTableList(SearchShareTableVo vo) {

        // 获得到要分享的列表
        List<DapDataModelShareTable> dapDataModelShareTables = getBaseMapper().selectList(new LambdaQueryWrapper<DapDataModelShareTable>()
                .eq(DapDataModelShareTable::getModelId, vo.getModelId()));
        List<String> registerIds = dapDataModelShareTables.stream().map(DapDataModelShareTable::getTableId).collect(Collectors.toList());
        IPage<DapDataModelTable> shareTableList = dapDataModelTableService.getShareTableList(vo, registerIds);
        List<DapDataModelTable> records = shareTableList.getRecords().stream()
                .peek(r -> r.setShareTable(registerIds.contains(r.getId()) ? true : false)).collect(Collectors.toList());
        if(!records.isEmpty()){
            // 获取分组id
            List<String> groupIds = records.stream().map(DapDataModelTable::getGroupId).collect(Collectors.toList());
            // 查询分组信息
            List<DapDataModelGroup> dapDataModelGroups = dapDataModelGroupService.getBaseMapper().selectBatchIds(groupIds);
            // 筛选出有父id的分组
            List<String> pidList = dapDataModelGroups.stream().filter(g -> isNotBlank(g.getPid()))
                    .map(DapDataModelGroup::getPid).collect(Collectors.toList());
            List<DapDataModelGroup> parentGroups = null;
            if(!pidList.isEmpty()){
                // 查询父分组信息
                parentGroups = dapDataModelGroupService.getBaseMapper().selectBatchIds(pidList);
            }
            // 父分组转化成map
            Map<String, String> parentName = parentGroups == null ? new HashMap<>() : parentGroups.stream()
                    .collect(Collectors.toMap(DapDataModelGroup::getId, DapDataModelGroup::getName));
            Map<String, String> groupAllPath = dapDataModelGroups.stream().collect(Collectors.toMap(DapDataModelGroup::getId,
                    p -> String.format("%s/%s", StringUtils.isBlank(parentName.get(p.getPid())) ? "" : parentName.get(p.getPid()) , p.getName())));
            List<DapDataModelTable> collect = records.stream().filter(r -> groupAllPath.containsKey(r.getGroupId()))
                    .peek(r -> r.setGroupPath(groupAllPath.get(r.getGroupId()))).collect(Collectors.toList());
            shareTableList.setRecords(collect);
        }
        return shareTableList;
    }

    @Override
    @Transactional
    public ResultBean<String> shareTable(List<String> tableIds) {
        // 查询表信息
        List<DapDataModelTable> dapDataModelTables = dapDataModelTableService.getBaseMapper().selectBatchIds(tableIds);
        if(dapDataModelTables.isEmpty()){
            return ResultBean.error("该模型中不存在选中的表");
        }
        String dataModelId = dapDataModelTables.stream().findFirst().get().getDataModelId();
        // 查询模型信息
        DapDataModel dapDataModel = dataModelService.getBaseMapper().selectById(dataModelId);
        if(!dapDataModel.getSysType().equals(SystemType.WAREHOUSE_SYS.getCode())){
            return ResultBean.error("该模型不是数仓模型，无法进行共享");
        }
        List<DapDataModelShareTable> dapDataModelShareTables = getBaseMapper().selectList(new LambdaQueryWrapper<DapDataModelShareTable>()
                .in(DapDataModelShareTable::getTableId, tableIds));
        List<String> collect = dapDataModelShareTables.stream().map(DapDataModelShareTable::getTableId).collect(Collectors.toList());
        if(collect.isEmpty()){
            List<DapDataModelShareTable> list = Lists.newArrayList();
            for (DapDataModelTable table : dapDataModelTables) {
                DapDataModelShareTable dapDataModelShareTable = new DapDataModelShareTable();
                dapDataModelShareTable.setModelId(table.getDataModelId());
                dapDataModelShareTable.setTableId(table.getId());
                dapDataModelShareTable.setSystemId(dapDataModel.getSystemId());
                list.add(dapDataModelShareTable);
            }
            return saveBatch(list) ? ResultBean.ok("共享成功") : ResultBean.error("共享失败");
        }else {
            List<String> tableNames = dapDataModelTables.stream().filter(d -> collect.contains(d.getId())).map(DapDataModelTable::getEngName).collect(Collectors.toList());
            return ResultBean.error(String.format("%s表已经共享", tableNames));
        }
    }

    @Override
    public ResultBean<String> shareTableCancel(List<String> tableIds) {

        List<DapDataModelShareTable> dapDataModelShareTables = getBaseMapper().selectList(new LambdaQueryWrapper<DapDataModelShareTable>()
                .in(DapDataModelShareTable::getTableId, tableIds));
        // 未共享的表id
        List<String> unShareIds = dapDataModelShareTables.stream().filter(d -> !tableIds.contains(d.getTableId()))
                .map(DapDataModelShareTable::getTableId).collect(Collectors.toList());
        if(unShareIds.isEmpty()){
            // 删除共享关系
            this.getBaseMapper().delete(new LambdaQueryWrapper<DapDataModelShareTable>().in(DapDataModelShareTable::getTableId, tableIds));
        }else{
            List<DapDataModelTable> dapDataModelTables = dapDataModelTableService.getBaseMapper().selectBatchIds(unShareIds);
            List<String> names = dapDataModelTables.stream().map(DapDataModelTable::getEngName).collect(Collectors.toList());
            return ResultBean.error(String.format("%s表未共享", names));
        }
        return ResultBean.ok("取消共享成功");
    }
}
